package com.adu.music.parser;

import com.adu.music.util.CommonUtils;
import com.adu.music.util.EncryptUtils;
import com.adu.music.util.JsoupUtils;
import com.adu.music.util.RegexUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author duchuanchuan
 * @date 2016/12/8
 */
public class MvParser {
    private static final Logger logger = LoggerFactory.getLogger(MvParser.class);

    /**
     * 根据mvID获取评论数量
     * "{"id":"376205","csrf_token":"338292eb905cbfde6a840e0922f63d3f"}"
     * @param mvId MV'ID
     * @return 评论数量
     */
    public static int parseComment(String mvId) {
        String url = "http://music.163.com/weapi/v1/resource/comments/R_MV_5_" + mvId + "/?csrf_token=";
        String params = "{\"id\":\"" + mvId + "\",\"csrf_token\":\"\"}";
        Map<String, String> encParams = EncryptUtils.neteaseParamsEncrypt(params);
        Optional<Document> documentOptional = JsoupUtils.post(url, encParams);
        if (documentOptional.isPresent()) {
            String resp = documentOptional.get().text();
            String comment = RegexUtils.getMatchedString("\"total\":(\\d+),", resp, 1);
            return CommonUtils.parseInt(comment);
        }
        logger.info("抓取MV评论数量异常,MVID:{}", mvId);
        return 0;
    }

    /**
     * 根据MVID解析MV信息
     * @param mvId mvId
     * @return MV详细信息
     */
    public static Map<String, Object> parseVideo(String mvId) {
        String url = "http://music.163.com/mv?id=" + mvId;
        Optional<Document> docOptional = JsoupUtils.get(url);
        final Map<String, Object> map = new HashMap<>();
        docOptional.ifPresent(doc -> {
            if(StringUtils.contains(doc.html(), "网页找不到")){
                logger.info("你要查找的网页找不到,url:{}", url);
                return;
            }
            Elements embeds = doc.getElementsByTag("embed ");
            if (embeds.size() == 0) return;
            Element h2 = doc.getElementById("flag_title1");
            // mv名字
            String mvName = h2.text();
            // 歌手
            Elements artistAnchors = doc.select(".title .name a");
            if (artistAnchors.size() == 0) return;
            Element artistAnchor = artistAnchors.get(0);
            String artistName = artistAnchor.text();
            String artistId = StringUtils.substringAfter(artistAnchor.attr("href"), "id=");
            Element embed = embeds.get(0);
            String flashVars = embed.attr("flashvars");
            String hurl = RegexUtils.getMatchedString("hurl=(.*?)&", flashVars, 1);
            String murl = RegexUtils.getMatchedString("murl=(.*?)&", flashVars, 1);
            int comment = parseComment(mvId);
            map.put("id", mvId);
            map.put("name", mvName);
            map.put("artist_id", artistId);
            map.put("artist_name", artistName);
            map.put("hurl", StringUtils.isBlank(hurl) ? "" : hurl);
            map.put("murl", StringUtils.isBlank(murl) ? "" : murl);
            map.put("comment", comment);
        });
        return map;
    }

    public static void readVideoToLocal(String mvUrl, String dstPath) {
        HttpClientBuilder builder = HttpClients.custom();
        HttpGet get = new HttpGet(mvUrl);
        get.addHeader("Connection", "keep-alive");
        //post.addHeader("Referer", "http://music.163.com/mv?id=5411025");
        get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
        get.addHeader("X-Requested-With", "ShockwaveFlash/23.0.0.207");
        HttpClient client = builder.build();
        try (FileOutputStream outputStream = new FileOutputStream(dstPath)) {
            HttpResponse response = client.execute(get);
            InputStream inputStream = response.getEntity().getContent();
            byte[] buff = new byte[4096];
            int len;
            while (0 < (len = inputStream.read(buff))) {
                outputStream.write(buff, 0, len);
            }
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Map<String, Object> map = parseVideo("411034");
        String hurl = (String) map.get("hurl");
        if (StringUtils.isNotBlank(hurl)) {
            String dstPath = "E:\\video\\mv\\" + RegexUtils.replaceSpecialChars(String.valueOf(map.get("name"))) + ".mp4";
            readVideoToLocal(hurl, dstPath);
        }
    }

}
